﻿using System;
using nRoute.Components.Composition;

namespace Orktane.ScriptActionModel
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true, Inherited = false)]
    public class MapScriptActionAttribute :  MapResourceBaseAttribute
    {

        const string TYPE_EXCEPTIONMSG = "{0} type must implement IScriptAction interface.";

        readonly string _prefix;
        readonly string _title;
        InstanceLifetime _lifetime = InstanceLifetime.PerInstance;

        public MapScriptActionAttribute(string prefix, string title)
        {
            if (string.IsNullOrEmpty(prefix)) throw new ArgumentNullException("prefix");
            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException("title");

            _prefix = prefix;
            _title = title;
        }

#region Properties

        public InstanceLifetime Lifetime
        {
            get { return _lifetime; }
            set { _lifetime = value; }
        }

        public string ShortDescription { get; set; }

        public string AdditionalDescription { get; set; }

        public Uri MoreInformationUrl { get; set; }

        public bool UnListed { get; set; }

#endregion

#region Overrides
		
		protected override Type GetResourceType(Type targetType)
        {
            return typeof(IScriptAction);
        }

        protected override bool CanInitialize(Type targetType)
        {
            return true;
        }

        protected override IResourceLocator GetResourceLocator(Type targetType)
        {
            // we check the given type implements 
            EnsureIsScriptAction(targetType);
            
            // and we get the resource locator
            return new DefaultScriptActionLocator(new ScriptActionMeta(targetType, _prefix, Lifetime,
                _title, ShortDescription, AdditionalDescription, MoreInformationUrl, UnListed));
        }

#endregion

#region Helpers

        protected void EnsureIsScriptAction(Type targetType)
        {
            if (!typeof(IScriptAction).IsAssignableFrom(targetType))
                throw new InvalidOperationException(string.Format(TYPE_EXCEPTIONMSG, targetType.FullName));
        }

#endregion	

    }
}
